namespace KanbanBoard.Tests.ApplicationSetup
{
    using System.Data;
    using System.Data.SqlClient;

    using Data.NHibernateMaps;

    using NHibernate.Cfg;
    using NHibernate.Tool.hbm2ddl;

    using NUnit.Framework;

    using SharpArch.Data.NHibernate;
    using SharpArch.Testing.NHibernate;

    [TestFixture]
    public class ApplicationDbSetUp 
    {
        readonly string[] mappingAssemblies = RepositoryTestsHelper.GetMappingAssemblies();
        const string ConfigurationFile = "../../../WebUI/NHibernate.config";

        private string GetDataBaseNameFromConnectionString(string theConfigConnStr)
        {
            return theConfigConnStr
                .Split(';')[1]
                .Split('=')[1];
        }

        private string PrepareMasterConnStr(string theConfigConnStr)
        {
            var userDbName = GetDataBaseNameFromConnectionString(theConfigConnStr);
            return theConfigConnStr.Replace(userDbName, "master");
        }

        [TestFixtureSetUp]
        public void SetUpFixture()
        {
            ServiceLocatorInitializer.Init();
        }

        private void BuildDbSchemaFromDomainMetadata()
        {
            var webAppConnectionStr = new Configuration()
                .Configure(ConfigurationFile)
                .Properties["connection.connection_string"];

            var originalDbName = GetDataBaseNameFromConnectionString(webAppConnectionStr);
            var masterConnString = PrepareMasterConnStr(webAppConnectionStr);

            using (var connection = new SqlConnection(masterConnString))
            {
                using (IDbCommand command = connection.CreateCommand())
                {
                    connection.Open();

                    command.CommandText =
                        @"IF EXISTS(SELECT name FROM master..sysdatabases WHERE name = N'@DB_NAME')
	                        BEGIN
	                           ALTER DATABASE @DB_NAME SET SINGLE_USER with ROLLBACK IMMEDIATE;
	                           DROP DATABASE @DB_NAME; 
	                        END
                        CREATE DATABASE @DB_NAME;"
                            .Replace("@DB_NAME", originalDbName);

                    command.ExecuteNonQuery();
                }

                connection.ChangeDatabase(originalDbName);

                var configuration = CreateAppConfiguration();
                new SchemaExport(configuration).Create(false, true);
            }
        }

        protected Configuration CreateAppConfiguration()
        {
            return NHibernateSession.Init(
                new SimpleSessionStorage(),
                mappingAssemblies,
                new AutoPersistenceModelGenerator().Generate(),
                ConfigurationFile
                );
        }

        [Test, Ignore("Run this test only if you want to recreate database Kanban with Production Data")]
        public void BuildSchemaAndDataForProduction()
        {
            BuildDbSchemaFromDomainMetadata();
            new DataProviderBuilder().Build();
        }
    }
}